#include "Geometry.h"
#include "Color.h"
#include <vector>
#include <glut.h>

#include "RayTracer.h"

RayTracing::Scene* s = new RayTracing::Scene( 0.0 , 10.0 , -400.0 );
RayTracing::RayTracer rt( s , 5 );

void display()
{
	rt.renderScene();

	glDrawPixels(rt.getWidth(), rt.getHeight(), GL_RGB, GL_FLOAT, rt.frameBuffer );

	glFlush();

}

int main(int argc, char **argv)
{
	glutInit(&argc,argv);
	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);
	glutInitWindowSize(rt.getWidth(),rt.getHeight());
	glutInitWindowPosition(100,100);
	glutCreateWindow("Ray Tracing");

	gluOrtho2D( 0, rt.getWidth() - 1, rt.getHeight() - 1, 0 );

	Properties::Color white( 1.0 , 1.0 , 1.0 );
	Properties::Color red( 1.0 , 0.0 , 0.0 );
	Properties::Color green( 0.0 , 1.0 , 0.0 );
	Properties::Color blue( 0.0 , 0.0 , 1.0 );

	//Sphere
	s->addObject( new Geometry::Sphere( Geometry::Point( -350.0 , 0.0 , 120.0  ), 
		                                100, 
										white, 
										Properties::Lighting( Properties::Ambient ( 0.2 , 0.2 , 0.2 ),
										                      Properties::Specular( 0.5 , 0.5 , 0.5 ),
															  Properties::Diffuse ( 0.5 , 0.5 , 0.5 ) ) ) );

	//Sphere2
	s->addObject( new Geometry::Sphere( Geometry::Point( 0.0 , 0.0 , 200.0 ), 
		                                200, 
										white, 
										Properties::Lighting( Properties::Ambient ( 0.0 , 0.0 , 0.2 ),
										                      Properties::Specular( 0.0 , 0.1 , 0.0 ),
															  Properties::Diffuse ( 0.0 , 0.5 , 0.0 ) ) ) );

	//Sphere3
	s->addObject( new Geometry::Sphere( Geometry::Point( 200.0 , 100.0 , 0.0 ), 
		                                100, 
										white, 
										Properties::Lighting( Properties::Ambient ( 0.0 , 0.2 , 0.0 ),
										                      Properties::Specular( 0.0 , 0.0 , 0.5 ),
															  Properties::Diffuse ( 0.0 , 0.0 , 0.5 ) ) ) );

	//Sphere4
	s->addObject( new Geometry::Sphere( Geometry::Point( 50.0 , 260.0 , 120.0  ), 
		                                100, 
										white, 
										Properties::Lighting( Properties::Ambient ( 0.2 , 0.2 , 0.2 ),
										                      Properties::Specular( 0.5 , 0.5 , 0.5 ),
															  Properties::Diffuse ( 0.5 , 0.5 , 0.5 ) ) ) );

	//Sphere5
	s->addObject( new Geometry::Sphere( Geometry::Point( -150.0 , 260.0 , 120.0  ), 
		                                60, 
										white, 
										Properties::Lighting( Properties::Ambient ( 0.2 , 0.2 , 0.2 ),
										                      Properties::Specular( 0.5 , 0.5 , 0.5 ),
															  Properties::Diffuse ( 0.5 , 0.5 , 0.5 ) ) ) );

	//Sphere6
	s->addObject( new Geometry::Sphere( Geometry::Point( -150.0 , -150.0 , 120.0 ), 
		                                120, 
										white, 
										Properties::Lighting( Properties::Ambient ( 0.0 , 0.0 , 0.2 ),
										                      Properties::Specular( 0.0 , 0.0 , 0.5 ),
															  Properties::Diffuse ( 0.0 , 0.0 , 0.5 ) ) ) );

	//Sphere7
	s->addObject( new Geometry::Sphere( Geometry::Point( -150.0 ,  200.0 , 120.0 ), 
		                                120, 
										white, 
										Properties::Lighting( Properties::Ambient ( 0.2 , 0.0 , 0.2 ),
										                      Properties::Specular( 0.5 , 0.0 , 0.5 ),
															  Properties::Diffuse ( 0.5 , 0.0 , 0.5 ) ) ) );
	//Sphere8
	s->addObject( new Geometry::Sphere( Geometry::Point(  -70.0 ,  -100.0 , 80.0 ), 
		                                80, 
										white, 
										Properties::Lighting( Properties::Ambient ( 0.0 , 0.2 , 0.2 ),
										                      Properties::Specular( 0.0 , 0.5 , 0.5 ),
															  Properties::Diffuse ( 0.0 , 0.5 , 0.5 ) ) ) );

	//Plane
	s->addObject( new Geometry::Plane( Geometry::Vector( 0.0 , 1.0 , -0.4 ), 
		                               Geometry::Point( 0.0 ,  -120.0 , 200.0 ), 
									   white, 
									   Properties::Lighting( Properties::Ambient ( 0.1 , 0.1 , 0.1 ),
										                      Properties::Specular( 0.7 , 0.7 , 0.7 ),
															  Properties::Diffuse ( 0.9 , 0.9 , 0.9 ) ) ) );

	//Plane2
	//s->addObject( new Geometry::Plane( Geometry::Vector( -1.0 , 0.0 ,  -0.3 ), 
	//	                               Geometry::Point(  50.0 , 0.0 , 200.0 ), 
	//								   white, 
	//								   Properties::Lighting( Properties::Ambient ( 0.1 , 0.1 , 0.1 ),
	//									                      Properties::Specular( 0.9 , 0.9 , 0.9 ),
	//														  Properties::Diffuse ( 0.3 , 0.3 , 0.3 ) ) ) );

	//Light
	s->addLight( new RayTracing::Light( Geometry::Point(     0.0 ,  1000.0 , -2000.0 ), 
		                                Properties::Color( 1.0 , 1.0 , 1.0 ) ) );

	s->addLight( new RayTracing::Light( Geometry::Point(   200.0 ,   400.0 ,   -200.0 ), white ) );

	s->setAmbient( Properties::Color( 0.2 , 0.2 , 0.2 ) );


	//Positive Y is up , Positive X is to right , Positive Z is far

	glutDisplayFunc( display );
	glutMainLoop();

	return 0;
}